﻿/* gost12.c - an implementation of the GOST R 34.11-2012 hash function,
 * the Russian cryptographic standard.
 * See also RFC 6986.
 *
 * Copyright (c) 2019, Aleksey Kravchenko <rhash.admin@gmail.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
 * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "gost12.h"
#include <string.h>
#include "byte_order.h"

#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__clang__) && !defined(RHASH_NO_ASM)
# define USE_GCC_ASM_IA32
#elif defined(__GNUC__) && defined(CPU_X64) && !defined(RHASH_NO_ASM)
# define USE_GCC_ASM_X64
#endif

ALIGN_ATTR(64)
static const uint64_t TR[8][256] =
{
	{
		I64(0xD01F715B5C7EF8E6),I64(0x16FA240980778325),I64(0xA8A42E857EE049C8),I64(0x6AC1068FA186465B),
		I64(0x6E417BD7A2E9320B),I64(0x665C8167A437DAAB),I64(0x7666681AA89617F6),I64(0x4B959163700BDCF5),
		I64(0xF14BE6B78DF36248),I64(0xC585BD689A625CFF),I64(0x9557D7FCA67D82CB),I64(0x89F0B969AF6DD366),
		I64(0xB0833D48749F6C35),I64(0xA1998C23B1ECBC7C),I64(0x8D70C431AC02A736),I64(0xD6DFBC2FD0A8B69E),
		I64(0x37AEB3E551FA198B),I64(0x0B7D128A40B5CF9C),I64(0x5A8F2008B5780CBC),I64(0xEDEC882284E333E5),
		I64(0xD25FC177D3C7C2CE),I64(0x5E0F5D50B61778EC),I64(0x1D873683C0C24CB9),I64(0xAD040BCBB45D208C),
		I64(0x2F89A0285B853C76),I64(0x5732FFF6791B8D58),I64(0x3E9311439EF6EC3F),I64(0xC9183A809FD3C00F),
		I64(0x83ADF3F5260A01EE),I64(0xA6791941F4E8EF10),I64(0x103AE97D0CA1CD5D),I64(0x2CE948121DEE1B4A),
		I64(0x39738421DBF2BF53),I64(0x093DA2A6CF0CF5B4),I64(0xCD9847D89CBCB45F),I64(0xF9561C078B2D8AE8),
		I64(0x9C6A755A6971777F),I64(0xBC1EBAA0712EF0C5),I64(0x72E61542ABF963A6),I64(0x78BB5FDE229EB12E),
		I64(0x14BA94250FCEB90D),I64(0x844D6697630E5282),I64(0x98EA08026A1E032F),I64(0xF06BBEA144217F5C),
		I64(0xDB6263D11CCB377A),I64(0x641C314B2B8EE083),I64(0x320E96AB9B4770CF),I64(0x1EE7DEB986A96B85),
		I64(0xE96CF57A878C47B5),I64(0xFDD6615F8842FEB8),I64(0xC83862965601DD1B),I64(0x2EA9F83E92572162),
		I64(0xF876441142FF97FC),I64(0xEB2C455608357D9D),I64(0x5612A7E0B0C9904C),I64(0x6C01CBFB2D500823),
		I64(0x4548A6A7FA037A2D),I64(0xABC4C6BF388B6EF4),I64(0xBADE77D4FDF8BEBD),I64(0x799B07C8EB4CAC3A),
		I64(0x0C9D87E805B19CF0),I64(0xCB588AAC106AFA27),I64(0xEA0C1D40C1E76089),I64(0x2869354A1E816F1A),
		I64(0xFF96D17307FBC490),I64(0x9F0A9D602F1A5043),I64(0x96373FC6E016A5F7),I64(0x5292DAB8B3A6E41C),
		I64(0x9B8AE0382C752413),I64(0x4F15EC3B7364A8A5),I64(0x3FB349555724F12B),I64(0xC7C50D4415DB66D7),
		I64(0x92B7429EE379D1A7),I64(0xD37F99611A15DFDA),I64(0x231427C05E34A086),I64(0xA439A96D7B51D538),
		I64(0xB403401077F01865),I64(0xDDA2AEA5901D7902),I64(0x0A5D4A9C8967D288),I64(0xC265280ADF660F93),
		I64(0x8BB0094520D4E94E),I64(0x2A29856691385532),I64(0x42A833C5BF072941),I64(0x73C64D54622B7EB2),
		I64(0x07E095624504536C),I64(0x8A905153E906F45A),I64(0x6F6123C16B3B2F1F),I64(0xC6E55552DC097BC3),
		I64(0x4468FEB133D16739),I64(0xE211E7F0C7398829),I64(0xA2F96419F7879B40),I64(0x19074BDBC3AD38E9),
		I64(0xF4EBC3F9474E0B0C),I64(0x43886BD376D53455),I64(0xD8028BEB5AA01046),I64(0x51F23282F5CDC320),
		I64(0xE7B1C2BE0D84E16D),I64(0x081DFAB006DEE8A0),I64(0x3B33340D544B857B),I64(0x7F5BCABC679AE242),
		I64(0x0EDD37C48A08A6D8),I64(0x81ED43D9A9B33BC6),I64(0xB1A3655EBD4D7121),I64(0x69A1EEB5E7ED6167),
		I64(0xF6AB73D5C8F73124),I64(0x1A67A3E185C61FD5),I64(0x2DC91004D43C065E),I64(0x0240B02C8FB93A28),
		I64(0x90F7F2B26CC0EB8F),I64(0x3CD3A16F114FD617),I64(0xAAE49EA9F15973E0),I64(0x06C0CD748CD64E78),
		I64(0xDA423BC7D5192A6E),I64(0xC345701C16B41287),I64(0x6D2193EDE4821537),I64(0xFCF639494190E3AC),
		I64(0x7C3B228621F1C57E),I64(0xFB16AC2B0494B0C0),I64(0xBF7E529A3745D7F9),I64(0x6881B6A32E3F7C73),
		I64(0xCA78D2BAD9B8E733),I64(0xBBFE2FC2342AA3A9),I64(0x0DBDDFFECC6381E4),I64(0x70A6A56E2440598E),
		I64(0xE4D12A844BEFC651),I64(0x8C509C2765D0BA22),I64(0xEE8C6018C28814D9),I64(0x17DA7C1F49A59E31),
		I64(0x609C4C1328E194D3),I64(0xB3E3D57232F44B09),I64(0x91D7AAA4A512F69B),I64(0x0FFD6FD243DABBCC),
		I64(0x50D26A943C1FDE34),I64(0x6BE15E9968545B4F),I64(0x94778FEA6FAF9FDF),I64(0x2B09DD7058EA4826),
		I64(0x677CD9716DE5C7BF),I64(0x49D5214FFFB2E6DD),I64(0x0360E83A466B273C),I64(0x1FC786AF4F7B7691),
		I64(0xA0B9D435783EA168),I64(0xD49F0C035F118CB6),I64(0x01205816C9D21D14),I64(0xAC2453DD7D8F3D98),
		I64(0x545217CC3F70AA64),I64(0x26B4028E9489C9C2),I64(0xDEC2469FD6765E3E),I64(0x04807D58036F7450),
		I64(0xE5F17292823DDB45),I64(0xF30B569B024A5860),I64(0x62DCFC3FA758AEFB),I64(0xE84CAD6C4E5E5AA1),
		I64(0xCCB81FCE556EA94B),I64(0x53B282AE7A74F908),I64(0x1B47FBF74C1402C1),I64(0x368EEBF39828049F),
		I64(0x7AFBEFF2AD278B06),I64(0xBE5E0A8CFE97CAED),I64(0xCFD8F7F413058E77),I64(0xF78B2BC301252C30),
		I64(0x4D555C17FCDD928D),I64(0x5F2F05467FC565F8),I64(0x24F4B2A21B30F3EA),I64(0x860DD6BBECB768AA),
		I64(0x4C750401350F8F99),I64(0x0000000000000000),I64(0xECCCD0344D312EF1),I64(0xB5231806BE220571),
		I64(0xC105C030990D28AF),I64(0x653C695DE25CFD97),I64(0x159ACC33C61CA419),I64(0xB89EC7F872418495),
		I64(0xA9847693B73254DC),I64(0x58CF90243AC13694),I64(0x59EFC832F3132B80),I64(0x5C4FED7C39AE42C4),
		I64(0x828DABE3EFD81CFA),I64(0xD13F294D95ACE5F2),I64(0x7D1B7A90E823D86A),I64(0xB643F03CF849224D),
		I64(0x3DF3F979D89DCB03),I64(0x7426D836272F2DDE),I64(0xDFE21E891FA4432A),I64(0x3A136C1B9D99986F),
		I64(0xFA36F43DCD46ADD4),I64(0xC025982650DF35BB),I64(0x856D3E81AADC4F96),I64(0xC4A5E57E53B041EB),
		I64(0x4708168B75BA4005),I64(0xAF44BBE73BE41AA4),I64(0x971767D029C4B8E3),I64(0xB9BE9FEEBB939981),
		I64(0x215497ECD18D9AAE),I64(0x316E7E91DD2C57F3),I64(0xCEF8AFE2DAD79363),I64(0x3853DC371220A247),
		I64(0x35EE03C9DE4323A3),I64(0xE6919AA8C456FC79),I64(0xE05157DC4880B201),I64(0x7BDBB7E464F59612),
		I64(0x127A59518318F775),I64(0x332ECEBD52956DDB),I64(0x8F30741D23BB9D1E),I64(0xD922D3FD93720D52),
		I64(0x7746300C61440AE2),I64(0x25D4EAB4D2E2EEFE),I64(0x75068020EEFD30CA),I64(0x135A01474ACAEA61),
		I64(0x304E268714FE4AE7),I64(0xA519F17BB283C82C),I64(0xDC82F6B359CF6416),I64(0x5BAF781E7CAA11A8),
		I64(0xB2C38D64FB26561D),I64(0x34CE5BDF17913EB7),I64(0x5D6FB56AF07C5FD0),I64(0x182713CD0A7F25FD),
		I64(0x9E2AC576E6C84D57),I64(0x9AAAB82EE5A73907),I64(0xA3D93C0F3E558654),I64(0x7E7B92AAAE48FF56),
		I64(0x872D8EAD256575BE),I64(0x41C8DBFFF96C0E7D),I64(0x99CA5014A3CC1E3B),I64(0x40E883E930BE1369),
		I64(0x1CA76E95091051AD),I64(0x4E35B42DBAB6B5B1),I64(0x05A0254ECABD6944),I64(0xE1710FCA8152AF15),
		I64(0xF22B0E8DCB984574),I64(0xB763A82A319B3F59),I64(0x63FCA4296E8AB3EF),I64(0x9D4A2D4CA0A36A6B),
		I64(0xE331BFE60EEB953D),I64(0xD5BF541596C391A2),I64(0xF5CB9BEF8E9C1618),I64(0x46284E9DBC685D11),
		I64(0x2074CFFA185F87BA),I64(0xBD3EE2B6B8FCEDD1),I64(0xAE64E3F1F23607B0),I64(0xFEB68965CE29D984),
		I64(0x55724FDAF6A2B770),I64(0x29496D5CD753720E),I64(0xA75941573D3AF204),I64(0x8E102C0BEA69800A),
		I64(0x111AB16BC573D049),I64(0xD7FFE439197AAB8A),I64(0xEFAC380E0B5A09CD),I64(0x48F579593660FBC9),
		I64(0x22347FD697E6BD92),I64(0x61BC1405E13389C7),I64(0x4AB5C975B9D9C1E1),I64(0x80CD1BCF606126D2),
		I64(0x7186FD78ED92449A),I64(0x93971A882AABCCB3),I64(0x88D0E17F66BFCE72),I64(0x27945A985D5BD4D6)
	},
	{
		I64(0xDE553F8C05A811C8),I64(0x1906B59631B4F565),I64(0x436E70D6B1964FF7),I64(0x36D343CB8B1E9D85),
		I64(0x843DFACC858AAB5A),I64(0xFDFC95C299BFC7F9),I64(0x0F634BDEA1D51FA2),I64(0x6D458B3B76EFB3CD),
		I64(0x85C3F77CF8593F80),I64(0x3C91315FBE737CB2),I64(0x2148B03366ACE398),I64(0x18F8B8264C6761BF),
		I64(0xC830C1C495C9FB0F),I64(0x981A76102086A0AA),I64(0xAA16012142F35760),I64(0x35CC54060C763CF6),
		I64(0x42907D66CC45DB2D),I64(0x8203D44B965AF4BC),I64(0x3D6F3CEFC3A0E868),I64(0xBC73FF69D292BDA7),
		I64(0x8722ED0102E20A29),I64(0x8F8185E8CD34DEB7),I64(0x9B0561DDA7EE01D9),I64(0x5335A0193227FAD6),
		I64(0xC9CECC74E81A6FD5),I64(0x54F5832E5C2431EA),I64(0x99E47BA05D553470),I64(0xF7BEE756ACD226CE),
		I64(0x384E05A5571816FD),I64(0xD1367452A47D0E6A),I64(0xF29FDE1C386AD85B),I64(0x320C77316275F7CA),
		I64(0xD0C879E2D9AE9AB0),I64(0xDB7406C69110EF5D),I64(0x45505E51A2461011),I64(0xFC029872E46C5323),
		I64(0xFA3CB6F5F7BC0CC5),I64(0x031F17CD8768A173),I64(0xBD8DF2D9AF41297D),I64(0x9D3B4F5AB43E5E3F),
		I64(0x4071671B36FEEE84),I64(0x716207E7D3E3B83D),I64(0x48D20FF2F9283A1A),I64(0x27769EB4757CBC7E),
		I64(0x5C56EBC793F2E574),I64(0xA48B474F9EF5DC18),I64(0x52CBADA94FF46E0C),I64(0x60C7DA982D8199C6),
		I64(0x0E9D466EDC068B78),I64(0x4EEC2175EAF865FC),I64(0x550B8E9E21F7A530),I64(0x6B7BA5BC653FEC2B),
		I64(0x5EB7F1BA6949D0DD),I64(0x57EA94E3DB4C9099),I64(0xF640EAE6D101B214),I64(0xDD4A284182C0B0BB),
		I64(0xFF1D8FBF6304F250),I64(0xB8ACCB933BF9D7E8),I64(0xE8867C478EB68C4D),I64(0x3F8E2692391BDDC1),
		I64(0xCB2FD60912A15A7C),I64(0xAEC935DBAB983D2F),I64(0xF55FFD2B56691367),I64(0x80E2CE366CE1C115),
		I64(0x179BF3F8EDB27E1D),I64(0x01FE0DB07DD394DA),I64(0xDA8A0B76ECC37B87),I64(0x44AE53E1DF9584CB),
		I64(0xB310B4B77347A205),I64(0xDFAB323C787B8512),I64(0x3B511268D070B78E),I64(0x65E6E3D2B9396753),
		I64(0x6864B271E2574D58),I64(0x259784C98FC789D7),I64(0x02E11A7DFABB35A9),I64(0x8841A6DFA337158B),
		I64(0x7ADE78C39B5DCDD0),I64(0xB7CF804D9A2CC84A),I64(0x20B6BD831B7F7742),I64(0x75BD331D3A88D272),
		I64(0x418F6AAB4B2D7A5E),I64(0xD9951CBB6BABDAF4),I64(0xB6318DFDE7FF5C90),I64(0x1F389B112264AA83),
		I64(0x492C024284FBAEC0),I64(0xE33A0363C608F9A0),I64(0x2688930408AF28A4),I64(0xC7538A1A341CE4AD),
		I64(0x5DA8E677EE2171AE),I64(0x8C9E92254A5C7FC4),I64(0x63D8CD55AAE938B5),I64(0x29EBD8DAA97A3706),
		I64(0x959827B37BE88AA1),I64(0x1484E4356ADADF6E),I64(0xA7945082199D7D6B),I64(0xBF6CE8A455FA1CD4),
		I64(0x9CC542EAC9EDCAE5),I64(0x79C16F0E1C356CA3),I64(0x89BFAB6FDEE48151),I64(0xD4174D1830C5F0FF),
		I64(0x9258048415EB419D),I64(0x6139D72850520D1C),I64(0x6A85A80C18EC78F1),I64(0xCD11F88E0171059A),
		I64(0xCCEFF53E7CA29140),I64(0xD229639F2315AF19),I64(0x90B91EF9EF507434),I64(0x5977D28D074A1BE1),
		I64(0x311360FCE51D56B9),I64(0xC093A92D5A1F2F91),I64(0x1A19A25BB6DC5416),I64(0xEB996B8A09DE2D3E),
		I64(0xFEE3820F1ED7668A),I64(0xD7085AD5B7AD518C),I64(0x7FFF41890FE53345),I64(0xEC5948BD67DDE602),
		I64(0x2FD5F65DBAAA68E0),I64(0xA5754AFFE32648C2),I64(0xF8DDAC880D07396C),I64(0x6FA491468C548664),
		I64(0x0C7C5C1326BDBED1),I64(0x4A33158F03930FB3),I64(0x699ABFC19F84D982),I64(0xE4FA2054A80B329C),
		I64(0x6707F9AF438252FA),I64(0x08A368E9CFD6D49E),I64(0x47B1442C58FD25B8),I64(0xBBB3DC5EBC91769B),
		I64(0x1665FE489061EAC7),I64(0x33F27A811FA66310),I64(0x93A609346838D547),I64(0x30ED6D4C98CEC263),
		I64(0x1DD9816CD8DF9F2A),I64(0x94662A03063B1E7B),I64(0x83FDD9FBEB896066),I64(0x7B207573E68E590A),
		I64(0x5F49FC0A149A4407),I64(0x343259B671A5A82C),I64(0xFBC2BB458A6F981F),I64(0xC272B350A0A41A38),
		I64(0x3AAF1FD8ADA32354),I64(0x6CBB868B0B3C2717),I64(0xA2B569C88D2583FE),I64(0xF180C9D1BF027928),
		I64(0xAF37386BD64BA9F5),I64(0x12BACAB2790A8088),I64(0x4C0D3B0810435055),I64(0xB2EEB9070E9436DF),
		I64(0xC5B29067CEA7D104),I64(0xDCB425F1FF132461),I64(0x4F122CC5972BF126),I64(0xAC282FA651230886),
		I64(0xE7E537992F6393EF),I64(0xE61B3A2952B00735),I64(0x709C0A57AE302CE7),I64(0xE02514AE416058D3),
		I64(0xC44C9DD7B37445DE),I64(0x5A68C5408022BA92),I64(0x1C278CDCA50C0BF0),I64(0x6E5A9CF6F18712BE),
		I64(0x86DCE0B17F319EF3),I64(0x2D34EC2040115D49),I64(0x4BCD183F7E409B69),I64(0x2815D56AD4A9A3DC),
		I64(0x24698979F2141D0D),I64(0x0000000000000000),I64(0x1EC696A15FB73E59),I64(0xD86B110B16784E2E),
		I64(0x8E7F8858B0E74A6D),I64(0x063E2E8713D05FE6),I64(0xE2C40ED3BBDB6D7A),I64(0xB1F1AECA89FC97AC),
		I64(0xE1DB191E3CB3CC09),I64(0x6418EE62C4EAF389),I64(0xC6AD87AA49CF7077),I64(0xD6F65765CA7EC556),
		I64(0x9AFB6C6DDA3D9503),I64(0x7CE05644888D9236),I64(0x8D609F95378FEB1E),I64(0x23A9AA4E9C17D631),
		I64(0x6226C0E5D73AAC6F),I64(0x56149953A69F0443),I64(0xEEB852C09D66D3AB),I64(0x2B0AC2A753C102AF),
		I64(0x07C023376E03CB3C),I64(0x2CCAE1903DC2C993),I64(0xD3D76E2F5EC63BC3),I64(0x9E2458973356FF4C),
		I64(0xA66A5D32644EE9B1),I64(0x0A427294356DE137),I64(0x783F62BE61E6F879),I64(0x1344C70204D91452),
		I64(0x5B96C8F0FDF12E48),I64(0xA90916ECC59BF613),I64(0xBE92E5142829880E),I64(0x727D102A548B194E),
		I64(0x1BE7AFEBCB0FC0CC),I64(0x3E702B2244C8491B),I64(0xD5E940A84D166425),I64(0x66F9F41F3E51C620),
		I64(0xABE80C913F20C3BA),I64(0xF07EC461C2D1EDF2),I64(0xF361D3AC45B94C81),I64(0x0521394A94B8FE95),
		I64(0xADD622162CF09C5C),I64(0xE97871F7F3651897),I64(0xF4A1F09B2BBA87BD),I64(0x095D6559B2054044),
		I64(0x0BBC7F2448BE75ED),I64(0x2AF4CF172E129675),I64(0x157AE98517094BB4),I64(0x9FDA55274E856B96),
		I64(0x914713499283E0EE),I64(0xB952C623462A4332),I64(0x74433EAD475B46A8),I64(0x8B5EB112245FB4F8),
		I64(0xA34B6478F0F61724),I64(0x11A5DD7FFE6221FB),I64(0xC16DA49D27CCBB4B),I64(0x76A224D0BDE07301),
		I64(0x8AA0BCA2598C2022),I64(0x4DF336B86D90C48F),I64(0xEA67663A740DB9E4),I64(0xEF465F70E0B54771),
		I64(0x39B008152ACB8227),I64(0x7D1E5BF4F55E06EC),I64(0x105BD0CF83B1B521),I64(0x775C2960C033E7DB),
		I64(0x7E014C397236A79F),I64(0x811CC386113255CF),I64(0xEDA7450D1A0E72D8),I64(0x5889DF3D7A998F3B),
		I64(0x2E2BFBEDC779FC3A),I64(0xCE0EEF438619A4E9),I64(0x372D4E7BF6CD095F),I64(0x04DF34FAE96B6A4F),
		I64(0xF923A13870D4ADB6),I64(0xA1AA7E050A4D228D),I64(0xA8F71B5CB84862C9),I64(0xB52E9A306097FDE3),
		I64(0x0D8251A35B6E2A0B),I64(0x2257A7FEE1C442EB),I64(0x73831D9A29588D94),I64(0x51D4BA64C89CCF7F),
		I64(0x502AB7D4B54F5BA5),I64(0x97793DCE8153BF08),I64(0xE5042DE4D5D8A646),I64(0x9687307EFC802BD2),
		I64(0xA05473B5779EB657),I64(0xB4D097801D446939),I64(0xCFF0E2F3FBCA3033),I64(0xC38CBEE0DD778EE2),
		I64(0x464F499C252EB162),I64(0xCAD1DBB96F72CEA6),I64(0xBA4DD1EEC142E241),I64(0xB00FA37AF42F0376)
	},
	{
		I64(0xCCE4CD3AA968B245),I64(0x089D5484E80B7FAF),I64(0x638246C1B3548304),I64(0xD2FE0EC8C2355492),
		I64(0xA7FBDF7FF2374EEE),I64(0x4DF1600C92337A16),I64(0x84E503EA523B12FB),I64(0x0790BBFD53AB0C4A),
		I64(0x198A780F38F6EA9D),I64(0x2AB30C8F55EC48CB),I64(0xE0F7FED6B2C49DB5),I64(0xB6ECF3F422CADBDC),
		I64(0x409C9A541358DF11),I64(0xD3CE8A56DFDE3FE3),I64(0xC3E9224312C8C1A0),I64(0x0D6DFA58816BA507),
		I64(0xDDF3E1B179952777),I64(0x04C02A42748BB1D9),I64(0x94C2ABFF9F2DECB8),I64(0x4F91752DA8F8ACF4),
		I64(0x78682BEFB169BF7B),I64(0xE1C77A48AF2FF6C4),I64(0x0C5D7EC69C80CE76),I64(0x4CC1E4928FD81167),
		I64(0xFEED3D24D9997B62),I64(0x518BB6DFC3A54A23),I64(0x6DBF2D26151F9B90),I64(0xB5BC624B05EA664F),
		I64(0xE86AAA525ACFE21A),I64(0x4801CED0FB53A0BE),I64(0xC91463E6C00868ED),I64(0x1027A815CD16FE43),
		I64(0xF67069A0319204CD),I64(0xB04CCC976C8ABCE7),I64(0xC0B9B3FC35E87C33),I64(0xF380C77C58F2DE65),
		I64(0x50BB3241DE4E2152),I64(0xDF93F490435EF195),I64(0xF1E0D25D62390887),I64(0xAF668BFB1A3C3141),
		I64(0xBC11B251F00A7291),I64(0x73A5EED47E427D47),I64(0x25BEE3F6EE4C3B2E),I64(0x43CC0BEB34786282),
		I64(0xC824E778DDE3039C),I64(0xF97D86D98A327728),I64(0xF2B043E24519B514),I64(0xE297EBF7880F4B57),
		I64(0x3A94A49A98FAB688),I64(0x868516CB68F0C419),I64(0xEFFA11AF0964EE50),I64(0xA4AB4EC0D517F37D),
		I64(0xA9C6B498547C567A),I64(0x8E18424F80FBBBB6),I64(0x0BCDC53BCF2BC23C),I64(0x137739AAEA3643D0),
		I64(0x2C1333EC1BAC2FF0),I64(0x8D48D3F0A7DB0625),I64(0x1E1AC3F26B5DE6D7),I64(0xF520F81F16B2B95E),
		I64(0x9F0F6EC450062E84),I64(0x0130849E1DEB6B71),I64(0xD45E31AB8C7533A9),I64(0x652279A2FD14E43F),
		I64(0x3209F01E70F1C927),I64(0xBE71A770CAC1A473),I64(0x0E3D6BE7A64B1894),I64(0x7EC8148CFF29D840),
		I64(0xCB7476C7FAC3BE0F),I64(0x72956A4A63A91636),I64(0x37F95EC21991138F),I64(0x9E3FEA5A4DED45F5),
		I64(0x7B38BA50964902E8),I64(0x222E580BBDE73764),I64(0x61E253E0899F55E6),I64(0xFC8D2805E352AD80),
		I64(0x35994BE3235AC56D),I64(0x09ADD01AF5E014DE),I64(0x5E8659A6780539C6),I64(0xB17C48097161D796),
		I64(0x026015213ACBD6E2),I64(0xD1AE9F77E515E901),I64(0xB7DC776A3F21B0AD),I64(0xABA6A1B96EB78098),
		I64(0x9BCF4486248D9F5D),I64(0x582666C536455EFD),I64(0xFDBDAC9BFEB9C6F1),I64(0xC47999BE4163CDEA),
		I64(0x765540081722A7EF),I64(0x3E548ED8EC710751),I64(0x3D041F67CB51BAC2),I64(0x7958AF71AC82D40A),
		I64(0x36C9DA5C047A78FE),I64(0xED9A048E33AF38B2),I64(0x26EE7249C96C86BD),I64(0x900281BDEBA65D61),
		I64(0x11172C8BD0FD9532),I64(0xEA0ABF73600434F8),I64(0x42FC8F75299309F3),I64(0x34A9CF7D3EB1AE1C),
		I64(0x2B838811480723BA),I64(0x5CE64C8742CEEF24),I64(0x1ADAE9B01FD6570E),I64(0x3C349BF9D6BAD1B3),
		I64(0x82453C891C7B75C0),I64(0x97923A40B80D512B),I64(0x4A61DBF1C198765C),I64(0xB48CE6D518010D3E),
		I64(0xCFB45C858E480FD6),I64(0xD933CBF30D1E96AE),I64(0xD70EA014AB558E3A),I64(0xC189376228031742),
		I64(0x9262949CD16D8B83),I64(0xEB3A3BED7DEF5F89),I64(0x49314A4EE6B8CBCF),I64(0xDCC3652F647E4C06),
		I64(0xDA635A4C2A3E2B3D),I64(0x470C21A940F3D35B),I64(0x315961A157D174B4),I64(0x6672E81DDA3459AC),
		I64(0x5B76F77A1165E36E),I64(0x445CB01667D36EC8),I64(0xC5491D205C88A69B),I64(0x456C34887A3805B9),
		I64(0xFFDDB9BAC4721013),I64(0x99AF51A71E4649BF),I64(0xA15BE01CBC7729D5),I64(0x52DB2760E485F7B0),
		I64(0x8C78576EBA306D54),I64(0xAE560F6507D75A30),I64(0x95F22F6182C687C9),I64(0x71C5FBF54489ABA5),
		I64(0xCA44F259E728D57E),I64(0x88B87D2CCEBBDC8D),I64(0xBAB18D32BE4A15AA),I64(0x8BE8EC93E99B611E),
		I64(0x17B713E89EBDF209),I64(0xB31C5D284BAA0174),I64(0xEECA9531148F8521),I64(0xB8D198138481C348),
		I64(0x8988F9B2D350B7FC),I64(0xB9E11C8D996AA839),I64(0x5A4673E40C8E881F),I64(0x1687977683569978),
		I64(0xBF4123EED72ACF02),I64(0x4EA1F1B3B513C785),I64(0xE767452BE16F91FF),I64(0x7505D1B730021A7C),
		I64(0xA59BCA5EC8FC980C),I64(0xAD069EDA20F7E7A3),I64(0x38F4B1BBA231606A),I64(0x60D2D77E94743E97),
		I64(0x9AFFC0183966F42C),I64(0x248E6768F3A7505F),I64(0xCDD449A4B483D934),I64(0x87B59255751BAF68),
		I64(0x1BEA6D2E023D3C7F),I64(0x6B1F12455B5FFCAB),I64(0x743555292DE9710D),I64(0xD8034F6D10F5FDDF),
		I64(0xC6198C9F7BA81B08),I64(0xBB8109ACA3A17EDB),I64(0xFA2D1766AD12CABB),I64(0xC729080166437079),
		I64(0x9C5FFF7B77269317),I64(0x0000000000000000),I64(0x15D706C9A47624EB),I64(0x6FDF38072FD44D72),
		I64(0x5FB6DD3865EE52B7),I64(0xA33BF53D86BCFF37),I64(0xE657C1B5FC84FA8E),I64(0xAA962527735CEBE9),
		I64(0x39C43525BFDA0B1B),I64(0x204E4D2A872CE186),I64(0x7A083ECE8BA26999),I64(0x554B9C9DB72EFBFA),
		I64(0xB22CD9B656416A05),I64(0x96A2BEDEA5E63A5A),I64(0x802529A826B0A322),I64(0x8115AD363B5BC853),
		I64(0x8375B81701901EB1),I64(0x3069E53F4A3A1FC5),I64(0xBD2136CFEDE119E0),I64(0x18BAFC91251D81EC),
		I64(0x1D4A524D4C7D5B44),I64(0x05F0AEDC6960DAA8),I64(0x29E39D3072CCF558),I64(0x70F57F6B5962C0D4),
		I64(0x989FD53903AD22CE),I64(0xF84D024797D91C59),I64(0x547B1803AAC5908B),I64(0xF0D056C37FD263F6),
		I64(0xD56EB535919E58D8),I64(0x1C7AD6D351963035),I64(0x2E7326CD2167F912),I64(0xAC361A443D1C8CD2),
		I64(0x697F076461942A49),I64(0x4B515F6FDC731D2D),I64(0x8AD8680DF4700A6F),I64(0x41AC1ECA0EB3B460),
		I64(0x7D988533D80965D3),I64(0xA8F6300649973D0B),I64(0x7765C4960AC9CC9E),I64(0x7CA801ADC5E20EA2),
		I64(0xDEA3700E5EB59AE4),I64(0xA06B6482A19C42A4),I64(0x6A2F96DB46B497DA),I64(0x27DEF6D7D487EDCC),
		I64(0x463CA5375D18B82A),I64(0xA6CB5BE1EFDC259F),I64(0x53EBA3FEF96E9CC1),I64(0xCE84D81B93A364A7),
		I64(0xF4107C810B59D22F),I64(0x333974806D1AA256),I64(0x0F0DEF79BBA073E5),I64(0x231EDC95A00C5C15),
		I64(0xE437D494C64F2C6C),I64(0x91320523F64D3610),I64(0x67426C83C7DF32DD),I64(0x6EEFBC99323F2603),
		I64(0x9D6F7BE56ACDF866),I64(0x5916E25B2BAE358C),I64(0x7FF89012E2C2B331),I64(0x035091BF2720BD93),
		I64(0x561B0D22900E4669),I64(0x28D319AE6F279E29),I64(0x2F43A2533C8C9263),I64(0xD09E1BE9F8FE8270),
		I64(0xF740ED3E2C796FBC),I64(0xDB53DED237D5404C),I64(0x62B2C25FAEBFE875),I64(0x0AFD41A5D2C0A94D),
		I64(0x6412FD3CE0FF8F4E),I64(0xE3A76F6995E42026),I64(0x6C8FA9B808F4F0E1),I64(0xC2D9A6DD0F23AAD1),
		I64(0x8F28C6D19D10D0C7),I64(0x85D587744FD0798A),I64(0xA20B71A39B579446),I64(0x684F83FA7C7F4138),
		I64(0xE507500ADBA4471D),I64(0x3F640A46F19A6C20),I64(0x1247BD34F7DD28A1),I64(0x2D23B77206474481),
		I64(0x93521002CC86E0F2),I64(0x572B89BC8DE52D18),I64(0xFB1D93F8B0F9A1CA),I64(0xE95A2ECC4724896B),
		I64(0x3BA420048511DDF9),I64(0xD63E248AB6BEE54B),I64(0x5DD6C8195F258455),I64(0x06A03F634E40673B),
		I64(0x1F2A476C76B68DA6),I64(0x217EC9B49AC78AF7),I64(0xECAA80102E4453C3),I64(0x14E78257B99D4F9A)
	},
	{
		I64(0x20329B2CC87BBA05),I64(0x4F5EB6F86546A531),I64(0xD4F44775F751B6B1),I64(0x8266A47B850DFA8B),
		I64(0xBB986AA15A6CA985),I64(0xC979EB08F9AE0F99),I64(0x2DA6F447A2375EA1),I64(0x1E74275DCD7D8576),
		I64(0xBC20180A800BC5F8),I64(0xB4A2F701B2DC65BE),I64(0xE726946F981B6D66),I64(0x48E6C453BF21C94C),
		I64(0x42CAD9930F0A4195),I64(0xEFA47B64AACCCD20),I64(0x71180A8960409A42),I64(0x8BB3329BF6A44E0C),
		I64(0xD34C35DE2D36DACC),I64(0xA92F5B7CBC23DC96),I64(0xB31A85AA68BB09C3),I64(0x13E04836A73161D2),
		I64(0xB24DFC4129C51D02),I64(0x8AE44B70B7DA5ACD),I64(0xE671ED84D96579A7),I64(0xA4BB3417D66F3832),
		I64(0x4572AB38D56D2DE8),I64(0xB1B47761EA47215C),I64(0xE81C09CF70ABA15D),I64(0xFFBDB872CE7F90AC),
		I64(0xA8782297FD5DC857),I64(0x0D946F6B6A4CE4A4),I64(0xE4DF1F4F5B995138),I64(0x9EBC71EDCA8C5762),
		I64(0x0A2C1DC0B02B88D9),I64(0x3B503C115D9D7B91),I64(0xC64376A8111EC3A2),I64(0xCEC199A323C963E4),
		I64(0xDC76A87EC58616F7),I64(0x09D596E073A9B487),I64(0x14583A9D7D560DAF),I64(0xF4C6DC593F2A0CB4),
		I64(0xDD21D19584F80236),I64(0x4A4836983DDDE1D3),I64(0xE58866A41AE745F9),I64(0xF591A5B27E541875),
		I64(0x891DC05074586693),I64(0x5B068C651810A89E),I64(0xA30346BC0C08544F),I64(0x3DBF3751C684032D),
		I64(0x2A1E86EC785032DC),I64(0xF73F5779FCA830EA),I64(0xB60C05CA30204D21),I64(0x0CC316802B32F065),
		I64(0x8770241BDD96BE69),I64(0xB861E18199EE95DB),I64(0xF805CAD91418FCD1),I64(0x29E70DCCBBD20E82),
		I64(0xC7140F435060D763),I64(0x0F3A9DA0E8B0CC3B),I64(0xA2543F574D76408E),I64(0xBD7761E1C175D139),
		I64(0x4B1F4F737CA3F512),I64(0x6DC2DF1F2FC137AB),I64(0xF1D05C3967B14856),I64(0xA742BF3715ED046C),
		I64(0x654030141D1697ED),I64(0x07B872ABDA676C7D),I64(0x3CE84EBA87FA17EC),I64(0xC1FB0403CB79AFDF),
		I64(0x3E46BC7105063F73),I64(0x278AE987121CD678),I64(0xA1ADB4778EF47CD0),I64(0x26DD906C5362C2B9),
		I64(0x05168060589B44E2),I64(0xFBFC41F9D79AC08F),I64(0x0E6DE44BA9CED8FA),I64(0x9FEB08068BF243A3),
		I64(0x7B341749D06B129B),I64(0x229C69E74A87929A),I64(0xE09EE6C4427C011B),I64(0x5692E30E725C4C3A),
		I64(0xDA99A33E5E9F6E4B),I64(0x353DD85AF453A36B),I64(0x25241B4C90E0FEE7),I64(0x5DE987258309D022),
		I64(0xE230140FC0802984),I64(0x93281E86A0C0B3C6),I64(0xF229D719A4337408),I64(0x6F6C2DD4AD3D1F34),
		I64(0x8EA5B2FBAE3F0AEE),I64(0x8331DD90C473EE4A),I64(0x346AA1B1B52DB7AA),I64(0xDF8F235E06042AA9),
		I64(0xCC6F6B68A1354B7B),I64(0x6C95A6F46EBF236A),I64(0x52D31A856BB91C19),I64(0x1A35DED6D498D555),
		I64(0xF37EAEF2E54D60C9),I64(0x72E181A9A3C2A61C),I64(0x98537AAD51952FDE),I64(0x16F6C856FFAA2530),
		I64(0xD960281E9D1D5215),I64(0x3A0745FA1CE36F50),I64(0x0B7B642BF1559C18),I64(0x59A87EAE9AEC8001),
		I64(0x5E100C05408BEC7C),I64(0x0441F98B19E55023),I64(0xD70DCC5534D38AEF),I64(0x927F676DE1BEA707),
		I64(0x9769E70DB925E3E5),I64(0x7A636EA29115065A),I64(0x468B201816EF11B6),I64(0xAB81A9B73EDFF409),
		I64(0xC0AC7DE88A07BB1E),I64(0x1F235EB68C0391B7),I64(0x6056B074458DD30F),I64(0xBE8EEAC102F7ED67),
		I64(0xCD381283E04B5FBA),I64(0x5CBEFECEC277C4E3),I64(0xD21B4C356C48CE0D),I64(0x1019C31664B35D8C),
		I64(0x247362A7D19EEA26),I64(0xEBE582EFB3299D03),I64(0x02AEF2CB82FC289F),I64(0x86275DF09CE8AAA8),
		I64(0x28B07427FAAC1A43),I64(0x38A9B7319E1F47CF),I64(0xC82E92E3B8D01B58),I64(0x06EF0B409B1978BC),
		I64(0x62F842BFC771FB90),I64(0x9904034610EB3B1F),I64(0xDED85AB5477A3E68),I64(0x90D195A663428F98),
		I64(0x5384636E2AC708D8),I64(0xCBD719C37B522706),I64(0xAE9729D76644B0EB),I64(0x7C8C65E20A0C7EE6),
		I64(0x80C856B007F1D214),I64(0x8C0B40302CC32271),I64(0xDBCEDAD51FE17A8A),I64(0x740E8AE938DBDEA0),
		I64(0xA615C6DC549310AD),I64(0x19CC55F6171AE90B),I64(0x49B1BDB8FE5FDD8D),I64(0xED0A89AF2830E5BF),
		I64(0x6A7AADB4F5A65BD6),I64(0x7E22972988F05679),I64(0xF952B3325566E810),I64(0x39FECEDADF61530E),
		I64(0x6101C99F04F3C7CE),I64(0x2E5F7F6761B562FF),I64(0xF08725D226CF5C97),I64(0x63AF3B54860FEF51),
		I64(0x8FF2CB10EF411E2F),I64(0x884AB9BB35267252),I64(0x4DF04433E7BA8DAE),I64(0x9AFD8866D3690741),
		I64(0x66B9BB34DE94ABB3),I64(0x9BAAF18D92171380),I64(0x543C11C5F0A064A5),I64(0x17A1B1BDBED431F1),
		I64(0xB5F58EEAF3A2717F),I64(0xC355F6C849858740),I64(0xEC5DF044694EF17E),I64(0xD83751F5DC6346D4),
		I64(0xFC4433520DFDACF2),I64(0x0000000000000000),I64(0x5A51F58E596EBC5F),I64(0x3285AAF12E34CF16),
		I64(0x8D5C39DB6DBD36B0),I64(0x12B731DDE64F7513),I64(0x94906C2D7AA7DFBB),I64(0x302B583AACC8E789),
		I64(0x9D45FACD090E6B3C),I64(0x2165E2C78905AEC4),I64(0x68D45F7F775A7349),I64(0x189B2C1D5664FDCA),
		I64(0xE1C99F2F030215DA),I64(0x6983269436246788),I64(0x8489AF3B1E148237),I64(0xE94B702431D5B59C),
		I64(0x33D2D31A6F4ADBD7),I64(0xBFD9932A4389F9A6),I64(0xB0E30E8AAB39359D),I64(0xD1E2C715AFCAF253),
		I64(0x150F43763C28196E),I64(0xC4ED846393E2EB3D),I64(0x03F98B20C3823C5E),I64(0xFD134AB94C83B833),
		I64(0x556B682EB1DE7064),I64(0x36C4537A37D19F35),I64(0x7559F30279A5CA61),I64(0x799AE58252973A04),
		I64(0x9C12832648707FFD),I64(0x78CD9C6913E92EC5),I64(0x1D8DAC7D0EFFB928),I64(0x439DA0784E745554),
		I64(0x413352B3CC887DCB),I64(0xBACF134A1B12BD44),I64(0x114EBAFD25CD494D),I64(0x2F08068C20CB763E),
		I64(0x76A07822BA27F63F),I64(0xEAB2FB04F25789C2),I64(0xE3676DE481FE3D45),I64(0x1B62A73D95E6C194),
		I64(0x641749FF5C68832C),I64(0xA5EC4DFC97112CF3),I64(0xF6682E92BDD6242B),I64(0x3F11C59A44782BB2),
		I64(0x317C21D1EDB6F348),I64(0xD65AB5BE75AD9E2E),I64(0x6B2DD45FB4D84F17),I64(0xFAAB381296E4D44E),
		I64(0xD0B5BEFEEEB4E692),I64(0x0882EF0B32D7A046),I64(0x512A91A5A83B2047),I64(0x963E9EE6F85BF724),
		I64(0x4E09CF132438B1F0),I64(0x77F701C9FB59E2FE),I64(0x7DDB1C094B726A27),I64(0x5F4775EE01F5F8BD),
		I64(0x9186EC4D223C9B59),I64(0xFEEAC1998F01846D),I64(0xAC39DB1CE4B89874),I64(0xB75B7C21715E59E0),
		I64(0xAFC0503C273AA42A),I64(0x6E3B543FEC430BF5),I64(0x704F7362213E8E83),I64(0x58FF0745DB9294C0),
		I64(0x67EEC2DF9FEABF72),I64(0xA0FACD9CCF8A6811),I64(0xB936986AD890811A),I64(0x95C715C63BD9CB7A),
		I64(0xCA8060283A2C33C7),I64(0x507DE84EE9453486),I64(0x85DED6D05F6A96F6),I64(0x1CDAD5964F81ADE9),
		I64(0xD5A33E9EB62FA270),I64(0x40642B588DF6690A),I64(0x7F75EEC2C98E42B8),I64(0x2CF18DACE3494A60),
		I64(0x23CB100C0BF9865B),I64(0xEEF3028FEBB2D9E1),I64(0x4425D2D394133929),I64(0xAAD6D05C7FA1E0C8),
		I64(0xAD6EA2F7A5C68CB5),I64(0xC2028F2308FB9381),I64(0x819F2F5B468FC6D5),I64(0xC5BAFD88D29CFFFC),
		I64(0x47DC59F357910577),I64(0x2B49FF07392E261D),I64(0x57C59AE5332258FB),I64(0x73B6F842E2BCB2DD),
		I64(0xCF96E04862B77725),I64(0x4CA73DD8A6C4996F),I64(0x015779EB417E14C1),I64(0x37932A9176AF8BF4)
	},
	{
		I64(0x190A2C9B249DF23E),I64(0x2F62F8B62263E1E9),I64(0x7A7F754740993655),I64(0x330B7BA4D5564D9F),
		I64(0x4C17A16A46672582),I64(0xB22F08EB7D05F5B8),I64(0x535F47F40BC148CC),I64(0x3AEC5D27D4883037),
		I64(0x10ED0A1825438F96),I64(0x516101F72C233D17),I64(0x13CC6F949FD04EAE),I64(0x739853C441474BFD),
		I64(0x653793D90D3F5B1B),I64(0x5240647B96B0FC2F),I64(0x0C84890AD27623E0),I64(0xD7189B32703AAEA3),
		I64(0x2685DE3523BD9C41),I64(0x99317C5B11BFFEFA),I64(0x0D9BAA854F079703),I64(0x70B93648FBD48AC5),
		I64(0xA80441FCE30BC6BE),I64(0x7287704BDC36FF1E),I64(0xB65384ED33DC1F13),I64(0xD36417343EE34408),
		I64(0x39CD38AB6E1BF10F),I64(0x5AB861770A1F3564),I64(0x0EBACF09F594563B),I64(0xD04572B884708530),
		I64(0x3CAE9722BDB3AF47),I64(0x4A556B6F2F5CBAF2),I64(0xE1704F1F76C4BD74),I64(0x5EC4ED7144C6DFCF),
		I64(0x16AFC01D4C7810E6),I64(0x283F113CD629CA7A),I64(0xAF59A8761741ED2D),I64(0xEED5A3991E215FAC),
		I64(0x3BF37EA849F984D4),I64(0xE413E096A56CE33C),I64(0x2C439D3A98F020D1),I64(0x637559DC6404C46B),
		I64(0x9E6C95D1E5F5D569),I64(0x24BB9836045FE99A),I64(0x44EFA466DAC8ECC9),I64(0xC6EAB2A5C80895D6),
		I64(0x803B50C035220CC4),I64(0x0321658CBA93C138),I64(0x8F9EBC465DC7EE1C),I64(0xD15A5137190131D3),
		I64(0x0FA5EC8668E5E2D8),I64(0x91C979578D1037B1),I64(0x0642CA05693B9F70),I64(0xEFCA80168350EB4F),
		I64(0x38D21B24F36A45EC),I64(0xBEAB81E1AF73D658),I64(0x8CBFD9CAE7542F24),I64(0xFD19CC0D81F11102),
		I64(0x0AC6430FBB4DBC90),I64(0x1D76A09D6A441895),I64(0x2A01573FF1CBBFA1),I64(0xB572E161894FDE2B),
		I64(0x8124734FA853B827),I64(0x614B1FDF43E6B1B0),I64(0x68AC395C4238CC18),I64(0x21D837BFD7F7B7D2),
		I64(0x20C714304A860331),I64(0x5CFAAB726324AA14),I64(0x74C5BA4EB50D606E),I64(0xF3A3030474654739),
		I64(0x23E671BCF015C209),I64(0x45F087E947B9582A),I64(0xD8BD77B418DF4C7B),I64(0xE06F6C90EBB50997),
		I64(0x0BD96080263C0873),I64(0x7E03F9410E40DCFE),I64(0xB8E94BE4C6484928),I64(0xFB5B0608E8CA8E72),
		I64(0x1A2B49179E0E3306),I64(0x4E29E76961855059),I64(0x4F36C4E6FCF4E4BA),I64(0x49740EE395CF7BCA),
		I64(0xC2963EA386D17F7D),I64(0x90D65AD810618352),I64(0x12D34C1B02A1FA4D),I64(0xFA44258775BB3A91),
		I64(0x18150F14B9EC46DD),I64(0x1491861E6B9A653D),I64(0x9A1019D7AB2C3FC2),I64(0x3668D42D06FE13D7),
		I64(0xDCC1FBB25606A6D0),I64(0x969490DD795A1C22),I64(0x3549B1A1BC6DD2EF),I64(0xC94F5E23A0ED770E),
		I64(0xB9F6686B5B39FDCB),I64(0xC4D4F4A6EFEAE00D),I64(0xE732851A1FFF2204),I64(0x94AAD6DE5EB869F9),
		I64(0x3F8FF2AE07206E7F),I64(0xFE38A9813B62D03A),I64(0xA7A1AD7A8BEE2466),I64(0x7B6056C8DDE882B6),
		I64(0x302A1E286FC58CA7),I64(0x8DA0FA457A259BC7),I64(0xB3302B64E074415B),I64(0x5402AE7EFF8B635F),
		I64(0x08F8050C9CAFC94B),I64(0xAE468BF98A3059CE),I64(0x88C355CCA98DC58F),I64(0xB10E6D67C7963480),
		I64(0xBAD70DE7E1AA3CF3),I64(0xBFB4A26E320262BB),I64(0xCB711820870F02D5),I64(0xCE12B7A954A75C9D),
		I64(0x563CE87DD8691684),I64(0x9F73B65E7884618A),I64(0x2B1E74B06CBA0B42),I64(0x47CEC1EA605B2DF1),
		I64(0x1C698312F735AC76),I64(0x5FDBCEFED9B76B2C),I64(0x831A354C8FB1CDFC),I64(0x820516C312C0791F),
		I64(0xB74CA762AEADABF0),I64(0xFC06EF821C80A5E1),I64(0x5723CBF24518A267),I64(0x9D4DF05D5F661451),
		I64(0x588627742DFD40BF),I64(0xDA8331B73F3D39A0),I64(0x17B0E392D109A405),I64(0xF965400BCF28FBA9),
		I64(0x7C3DBF4229A2A925),I64(0x023E460327E275DB),I64(0x6CD0B55A0CE126B3),I64(0xE62DA695828E96E7),
		I64(0x42AD6E63B3F373B9),I64(0xE50CC319381D57DF),I64(0xC5CBD729729B54EE),I64(0x46D1E265FD2A9912),
		I64(0x6428B056904EEFF8),I64(0x8BE23040131E04B7),I64(0x6709D5DA2ADD2EC0),I64(0x075DE98AF44A2B93),
		I64(0x8447DCC67BFBE66F),I64(0x6616F655B7AC9A23),I64(0xD607B8BDED4B1A40),I64(0x0563AF89D3A85E48),
		I64(0x3DB1B4AD20C21BA4),I64(0x11F22997B8323B75),I64(0x292032B34B587E99),I64(0x7F1CDACE9331681D),
		I64(0x8E819FC9C0B65AFF),I64(0xA1E3677FE2D5BB16),I64(0xCD33D225EE349DA5),I64(0xD9A2543B85AEF898),
		I64(0x795E10CBFA0AF76D),I64(0x25A4BBB9992E5D79),I64(0x78413344677B438E),I64(0xF0826688CEF68601),
		I64(0xD27B34BBA392F0EB),I64(0x551D8DF162FAD7BC),I64(0x1E57C511D0D7D9AD),I64(0xDEFFBDB171E4D30B),
		I64(0xF4FEEA8E802F6CAA),I64(0xA480C8F6317DE55E),I64(0xA0FC44F07FA40FF5),I64(0x95B5F551C3C9DD1A),
		I64(0x22F952336D6476EA),I64(0x0000000000000000),I64(0xA6BE8EF5169F9085),I64(0xCC2CF1AA73452946),
		I64(0x2E7DDB39BF12550A),I64(0xD526DD3157D8DB78),I64(0x486B2D6C08BECF29),I64(0x9B0F3A58365D8B21),
		I64(0xAC78CDFAADD22C15),I64(0xBC95C7E28891A383),I64(0x6A927F5F65DAB9C3),I64(0xC3891D2C1BA0CB9E),
		I64(0xEAA92F9F50F8B507),I64(0xCF0D9426C9D6E87E),I64(0xCA6E3BAF1A7EB636),I64(0xAB25247059980786),
		I64(0x69B31AD3DF4978FB),I64(0xE2512A93CC577C4C),I64(0xFF278A0EA61364D9),I64(0x71A615C766A53E26),
		I64(0x89DC764334FC716C),I64(0xF87A638452594F4A),I64(0xF2BC208BE914F3DA),I64(0x8766B94AC1682757),
		I64(0xBBC82E687CDB8810),I64(0x626A7A53F9757088),I64(0xA2C202F358467A2E),I64(0x4D0882E5DB169161),
		I64(0x09E7268301DE7DA8),I64(0xE897699C771AC0DC),I64(0xC8507DAC3D9CC3ED),I64(0xC0A878A0A1330AA6),
		I64(0x978BB352E42BA8C1),I64(0xE9884A13EA6B743F),I64(0x279AFDBABECC28A2),I64(0x047C8C064ED9EAAB),
		I64(0x507E2278B15289F4),I64(0x599904FBB08CF45C),I64(0xBD8AE46D15E01760),I64(0x31353DA7F2B43844),
		I64(0x8558FF49E68A528C),I64(0x76FBFC4D92EF15B5),I64(0x3456922E211C660C),I64(0x86799AC55C1993B4),
		I64(0x3E90D1219A51DA9C),I64(0x2D5CBEB505819432),I64(0x982E5FD48CCE4A19),I64(0xDB9C1238A24C8D43),
		I64(0xD439FEBECAA96F9B),I64(0x418C0BEF0960B281),I64(0x158EA591F6EBD1DE),I64(0x1F48E69E4DA66D4E),
		I64(0x8AFD13CF8E6FB054),I64(0xF5E1C9011D5ED849),I64(0xE34E091C5126C8AF),I64(0xAD67EE7530A398F6),
		I64(0x43B24DEC2E82C75A),I64(0x75DA99C1287CD48D),I64(0x92E81CDB3783F689),I64(0xA3DD217CC537CECD),
		I64(0x60543C50DE970553),I64(0x93F73F54AAF2426A),I64(0xA91B62737E7A725D),I64(0xF19D4507538732E2),
		I64(0x77E4DFC20F9EA156),I64(0x7D229CCDB4D31DC6),I64(0x1B346A98037F87E5),I64(0xEDF4C615A4B29E94),
		I64(0x4093286094110662),I64(0xB0114EE85AE78063),I64(0x6FF1D0D6B672E78B),I64(0x6DCF96D591909250),
		I64(0xDFE09E3EEC9567E8),I64(0x3214582B4827F97C),I64(0xB46DC2EE143E6AC8),I64(0xF6C0AC8DA7CD1971),
		I64(0xEBB60C10CD8901E4),I64(0xF7DF8F023ABCAD92),I64(0x9C52D3D2C217A0B2),I64(0x6B8D5CD0F8AB0D20),
		I64(0x3777F7A29B8FA734),I64(0x011F238F9D71B4E3),I64(0xC1B75B2F3C42BE45),I64(0x5DE588FDFE551EF7),
		I64(0x6EEEF3592B035368),I64(0xAA3A07FFC4E9B365),I64(0xECEBE59A39C32A77),I64(0x5BA742F8976E8187),
		I64(0x4B4A48E0B22D0E11),I64(0xDDDED83DCB771233),I64(0xA59FEB79AC0C51BD),I64(0xC7F5912A55792135)
	},
	{
		I64(0x6D6AE04668A9B08A),I64(0x3AB3F04B0BE8C743),I64(0xE51E166B54B3C908),I64(0xBE90A9EB35C2F139),
		I64(0xB2C7066637F2BEC1),I64(0xAA6945613392202C),I64(0x9A28C36F3B5201EB),I64(0xDDCE5A93AB536994),
		I64(0x0E34133EF6382827),I64(0x52A02BA1EC55048B),I64(0xA2F88F97C4B2A177),I64(0x8640E513CA2251A5),
		I64(0xCDF1D36258137622),I64(0xFE6CB708DEDF8DDB),I64(0x8A174A9EC8121E5D),I64(0x679896036B81560E),
		I64(0x59ED033395795FEE),I64(0x1DD778AB8B74EDAF),I64(0xEE533EF92D9F926D),I64(0x2A8C79BAF8A8D8F5),
		I64(0x6BCF398E69B119F6),I64(0xE20491742FAFDD95),I64(0x276488E0809C2AEC),I64(0xEA955B82D88F5CCE),
		I64(0x7102C63A99D9E0C4),I64(0xF9763017A5C39946),I64(0x429FA2501F151B3D),I64(0x4659C72BEA05D59E),
		I64(0x984B7FDCCF5A6634),I64(0xF742232953FBB161),I64(0x3041860E08C021C7),I64(0x747BFD9616CD9386),
		I64(0x4BB1367192312787),I64(0x1B72A1638A6C44D3),I64(0x4A0E68A6E8359A66),I64(0x169A5039F258B6CA),
		I64(0xB98A2EF44EDEE5A4),I64(0xD9083FE85E43A737),I64(0x967F6CE239624E13),I64(0x8874F62D3C1A7982),
		I64(0x3C1629830AF06E3F),I64(0x9165EBFD427E5A8E),I64(0xB5DD81794CEEAA5C),I64(0x0DE8F15A7834F219),
		I64(0x70BD98EDE3DD5D25),I64(0xACCC9CA9328A8950),I64(0x56664EDA1945CA28),I64(0x221DB34C0F8859AE),
		I64(0x26DBD637FA98970D),I64(0x1ACDFFB4F068F932),I64(0x4585254F64090FA0),I64(0x72DE245E17D53AFA),
		I64(0x1546B25D7C546CF4),I64(0x207E0FFFFB803E71),I64(0xFAAAD2732BCF4378),I64(0xB462DFAE36EA17BD),
		I64(0xCF926FD1AC1B11FD),I64(0xE0672DC7DBA7BA4A),I64(0xD3FA49AD5D6B41B3),I64(0x8BA81449B216A3BC),
		I64(0x14F9EC8A0650D115),I64(0x40FC1EE3EB1D7CE2),I64(0x23A2ED9B758CE44F),I64(0x782C521B14FDDC7E),
		I64(0x1C68267CF170504E),I64(0xBCF31558C1CA96E6),I64(0xA781B43B4BA6D235),I64(0xF6FD7DFE29FF0C80),
		I64(0xB0A4BAD5C3FAD91E),I64(0xD199F51EA963266C),I64(0x414340349119C103),I64(0x5405F269ED4DADF7),
		I64(0xABD61BB649969DCD),I64(0x6813DBEAE7BDC3C8),I64(0x65FB2AB09F8931D1),I64(0xF1E7FAE152E3181D),
		I64(0xC1A67CEF5A2339DA),I64(0x7A4FEEA8E0F5BBA1),I64(0x1E0B9ACF05783791),I64(0x5B8EBF8061713831),
		I64(0x80E53CDBCB3AF8D9),I64(0x7E898BD315E57502),I64(0xC6BCFBF0213F2D47),I64(0x95A38E86B76E942D),
		I64(0x092E94218D243CBA),I64(0x8339DEBF453622E7),I64(0xB11BE402B9FE64FF),I64(0x57D9100D634177C9),
		I64(0xCC4E8DB52217CBC3),I64(0x3B0CAE9C71EC7AA2),I64(0xFB158CA451CBFE99),I64(0x2B33276D82AC6514),
		I64(0x01BF5ED77A04BDE1),I64(0xC5601994AF33F779),I64(0x75C4A3416CC92E67),I64(0xF3844652A6EB7FC2),
		I64(0x3487E375FDD0EF64),I64(0x18AE430704609EED),I64(0x4D14EFB993298EFB),I64(0x815A620CB13E4538),
		I64(0x125C354207487869),I64(0x9EEEA614CE42CF48),I64(0xCE2D3106D61FAC1C),I64(0xBBE99247BAD6827B),
		I64(0x071A871F7B1C149D),I64(0x2E4A1CC10DB81656),I64(0x77A71FF298C149B8),I64(0x06A5D9C80118A97C),
		I64(0xAD73C27E488E34B1),I64(0x443A7B981E0DB241),I64(0xE3BBCFA355AB6074),I64(0x0AF276450328E684),
		I64(0x73617A896DD1871B),I64(0x58525DE4EF7DE20F),I64(0xB7BE3DCAB8E6CD83),I64(0x19111DD07E64230C),
		I64(0x842359A03E2A367A),I64(0x103F89F1F3401FB6),I64(0xDC710444D157D475),I64(0xB835702334DA5845),
		I64(0x4320FC876511A6DC),I64(0xD026ABC9D3679B8D),I64(0x17250EEE885C0B2B),I64(0x90DAB52A387AE76F),
		I64(0x31FED8D972C49C26),I64(0x89CBA8FA461EC463),I64(0x2FF5421677BCABB7),I64(0x396F122F85E41D7D),
		I64(0xA09B332430BAC6A8),I64(0xC888E8CED7070560),I64(0xAEAF201AC682EE8F),I64(0x1180D7268944A257),
		I64(0xF058A43628E7A5FC),I64(0xBD4C4B8FBBCE2B07),I64(0xA1246DF34ABE7B49),I64(0x7D5569B79BE9AF3C),
		I64(0xA9B5A705BD9EFA12),I64(0xDB6B835BAA4BC0E8),I64(0x05793BAC8F147342),I64(0x21C1512881848390),
		I64(0xFDB0556C50D357E5),I64(0x613D4FCB6A99FF72),I64(0x03DCE2648E0CDA3E),I64(0xE949B9E6568386F0),
		I64(0xFC0F0BBB2AD7EA04),I64(0x6A70675913B5A417),I64(0x7F36D5046FE1C8E3),I64(0x0C57AF8D02304FF8),
		I64(0x32223ABDFCC84618),I64(0x0891CAF6F720815B),I64(0xA63EEAEC31A26FD4),I64(0x2507345374944D33),
		I64(0x49D28AC266394058),I64(0xF5219F9AA7F3D6BE),I64(0x2D96FEA583B4CC68),I64(0x5A31E1571B7585D0),
		I64(0x8ED12FE53D02D0FE),I64(0xDFADE6205F5B0E4B),I64(0x4CABB16EE92D331A),I64(0x04C6657BF510CEA3),
		I64(0xD73C2CD6A87B8F10),I64(0xE1D87310A1A307AB),I64(0x6CD5BE9112AD0D6B),I64(0x97C032354366F3F2),
		I64(0xD4E0CEB22677552E),I64(0x0000000000000000),I64(0x29509BDE76A402CB),I64(0xC27A9E8BD42FE3E4),
		I64(0x5EF7842CEE654B73),I64(0xAF107ECDBC86536E),I64(0x3FCACBE784FCB401),I64(0xD55F90655C73E8CF),
		I64(0xE6C2F40FDABF1336),I64(0xE8F6E7312C873B11),I64(0xEB2A0555A28BE12F),I64(0xE4A148BC2EB774E9),
		I64(0x9B979DB84156BC0A),I64(0x6EB60222E6A56AB4),I64(0x87FFBBC4B026EC44),I64(0xC703A5275B3B90A6),
		I64(0x47E699FC9001687F),I64(0x9C8D1AA73A4AA897),I64(0x7CEA3760E1ED12DD),I64(0x4EC80DDD1D2554C5),
		I64(0x13E36B957D4CC588),I64(0x5D2B66486069914D),I64(0x92B90999CC7280B0),I64(0x517CC9C56259DEB5),
		I64(0xC937B619AD03B881),I64(0xEC30824AD997F5B2),I64(0xA45D565FC5AA080B),I64(0xD6837201D27F32F1),
		I64(0x635EF3789E9198AD),I64(0x531F75769651B96A),I64(0x4F77530A6721E924),I64(0x486DD4151C3DFDB9),
		I64(0x5F48DAFB9461F692),I64(0x375B011173DC355A),I64(0x3DA9775470F4D3DE),I64(0x8D0DCD81B30E0AC0),
		I64(0x36E45FC609D888BB),I64(0x55BAACBE97491016),I64(0x8CB29356C90AB721),I64(0x76184125E2C5F459),
		I64(0x99F4210BB55EDBD5),I64(0x6F095CF59CA1D755),I64(0x9F51F8C3B44672A9),I64(0x3538BDA287D45285),
		I64(0x50C39712185D6354),I64(0xF23B1885DCEFC223),I64(0x79930CCC6EF9619F),I64(0xED8FDC9DA3934853),
		I64(0xCB540AAA590BDF5E),I64(0x5C94389F1A6D2CAC),I64(0xE77DAAD8A0BBAED7),I64(0x28EFC5090CA0BF2A),
		I64(0xBF2FF73C4FC64CD8),I64(0xB37858B14DF60320),I64(0xF8C96EC0DFC724A7),I64(0x828680683F329F06),
		I64(0x941CD051CD6A29CC),I64(0xC3C5C05CAE2B5E05),I64(0xB601631DC2E27062),I64(0xC01922382027843B),
		I64(0x24B86A840E90F0D2),I64(0xD245177A276FFC52),I64(0x0F8B4DE98C3C95C6),I64(0x3E759530FEF809E0),
		I64(0x0B4D2892792C5B65),I64(0xC4DF4743D5374A98),I64(0xA5E20888BFAEB5EA),I64(0xBA56CC90C0D23F9A),
		I64(0x38D04CF8FFE0A09C),I64(0x62E1ADAFE495254C),I64(0x0263BCB3F40867DF),I64(0xCAEB547D230F62BF),
		I64(0x6082111C109D4293),I64(0xDAD4DD8CD04F7D09),I64(0xEFEC602E579B2F8C),I64(0x1FB4C4187F7C8A70),
		I64(0xFFD3E9DFA4DB303A),I64(0x7BF0B07F9AF10640),I64(0xF49EC14DDDF76B5F),I64(0x8F6E713247066D1F),
		I64(0x339D646A86CCFBF9),I64(0x64447467E58D8C30),I64(0x2C29A072F9B07189),I64(0xD8B7613F24471AD6),
		I64(0x6627C8D41185EBEF),I64(0xA347D140BEB61C96),I64(0xDE12B8F7255FB3AA),I64(0x9D324470404E1576),
		I64(0x9306574EB6763D51),I64(0xA80AF9D2C79A47F3),I64(0x859C0777442E8B9B),I64(0x69AC853D9DB97E29)
	},
	{
		I64(0xC3407DFC2DE6377E),I64(0x5B9E93EEA4256F77),I64(0xADB58FDD50C845E0),I64(0x5219FF11A75BED86),
		I64(0x356B61CFD90B1DE9),I64(0xFB8F406E25ABE037),I64(0x7A5A0231C0F60796),I64(0x9D3CD216E1F5020B),
		I64(0x0C6550FB6B48D8F3),I64(0xF57508C427FF1C62),I64(0x4AD35FFA71CB407D),I64(0x6290A2DA1666AA6D),
		I64(0xE284EC2349355F9F),I64(0xB3C307C53D7C84EC),I64(0x05E23C0468365A02),I64(0x190BAC4D6C9EBFA8),
		I64(0x94BBBEE9E28B80FA),I64(0xA34FC777529CB9B5),I64(0xCC7B39F095BCD978),I64(0x2426ADDB0CE532E3),
		I64(0x7E79329312CE4FC7),I64(0xAB09A72EEBEC2917),I64(0xF8D15499F6B9D6C2),I64(0x1A55B8BABF8C895D),
		I64(0xDB8ADD17FB769A85),I64(0xB57F2F368658E81B),I64(0x8ACD36F18F3F41F6),I64(0x5CE3B7BBA50F11D3),
		I64(0x114DCC14D5EE2F0A),I64(0xB91A7FCDED1030E8),I64(0x81D5425FE55DE7A1),I64(0xB6213BC1554ADEEE),
		I64(0x80144EF95F53F5F2),I64(0x1E7688186DB4C10C),I64(0x3B912965DB5FE1BC),I64(0xC281715A97E8252D),
		I64(0x54A5D7E21C7F8171),I64(0x4B12535CCBC5522E),I64(0x1D289CEFBEA6F7F9),I64(0x6EF5F2217D2E729E),
		I64(0xE6A7DC819B0D17CE),I64(0x1B94B41C05829B0E),I64(0x33D7493C622F711E),I64(0xDCF7F942FA5CE421),
		I64(0x600FBA8B7F7A8ECB),I64(0x46B60F011A83988E),I64(0x235B898E0DCF4C47),I64(0x957AB24F588592A9),
		I64(0x4354330572B5C28C),I64(0xA5F3EF84E9B8D542),I64(0x8C711E02341B2D01),I64(0x0B1874AE6A62A657),
		I64(0x1213D8E306FC19FF),I64(0xFE6D7C6A4D9DBA35),I64(0x65ED868F174CD4C9),I64(0x88522EA0E6236550),
		I64(0x899322065C2D7703),I64(0xC01E690BFEF4018B),I64(0x915982ED8ABDDAF8),I64(0xBE675B98EC3A4E4C),
		I64(0xA996BF7F82F00DB1),I64(0xE1DAF8D49A27696A),I64(0x2EFFD5D3DC8986E7),I64(0xD153A51F2B1A2E81),
		I64(0x18CAA0EBD690ADFB),I64(0x390E3134B243C51A),I64(0x2778B92CDFF70416),I64(0x029F1851691C24A6),
		I64(0x5E7CAFEACC133575),I64(0xFA4E4CC89FA5F264),I64(0x5A5F9F481E2B7D24),I64(0x484C47AB18D764DB),
		I64(0x400A27F2A1A7F479),I64(0xAEEB9B2A83DA7315),I64(0x721C626879869734),I64(0x042330A2D2384851),
		I64(0x85F672FD3765AFF0),I64(0xBA446B3A3E02061D),I64(0x73DD6ECEC3888567),I64(0xFFAC70CCF793A866),
		I64(0xDFA9EDB5294ED2D4),I64(0x6C6AEA7014325638),I64(0x834A5A0E8C41C307),I64(0xCDBA35562FB2CB2B),
		I64(0x0AD97808D06CB404),I64(0x0F3B440CB85AEE06),I64(0xE5F9C876481F213B),I64(0x98DEEE1289C35809),
		I64(0x59018BBFCD394BD1),I64(0xE01BF47220297B39),I64(0xDE68E1139340C087),I64(0x9FA3CA4788E926AD),
		I64(0xBB85679C840C144E),I64(0x53D8F3B71D55FFD5),I64(0x0DA45C5DD146CAA0),I64(0x6F34FE87C72060CD),
		I64(0x57FBC315CF6DB784),I64(0xCEE421A1FCA0FDDE),I64(0x3D2D0196607B8D4B),I64(0x642C8A29AD42C69A),
		I64(0x14AFF010BDD87508),I64(0xAC74837BEAC657B3),I64(0x3216459AD821634D),I64(0x3FB219C70967A9ED),
		I64(0x06BC28F3BB246CF7),I64(0xF2082C9126D562C6),I64(0x66B39278C45EE23C),I64(0xBD394F6F3F2878B9),
		I64(0xFD33689D9E8F8CC0),I64(0x37F4799EB017394F),I64(0x108CC0B26FE03D59),I64(0xDA4BD1B1417888D6),
		I64(0xB09D1332EE6EB219),I64(0x2F3ED975668794B4),I64(0x58C0871977375982),I64(0x7561463D78ACE990),
		I64(0x09876CFF037E82F1),I64(0x7FB83E35A8C05D94),I64(0x26B9B58A65F91645),I64(0xEF20B07E9873953F),
		I64(0x3148516D0B3355B8),I64(0x41CB2B541BA9E62A),I64(0x790416C613E43163),I64(0xA011D380818E8F40),
		I64(0x3A5025C36151F3EF),I64(0xD57095BDF92266D0),I64(0x498D4B0DA2D97688),I64(0x8B0C3A57353153A5),
		I64(0x21C491DF64D368E1),I64(0x8F2F0AF5E7091BF4),I64(0x2DA1C1240F9BB012),I64(0xC43D59A92CCC49DA),
		I64(0xBFA6573E56345C1F),I64(0x828B56A8364FD154),I64(0x9A41F643E0DF7CAF),I64(0xBCF843C985266AEA),
		I64(0x2B1DE9D7B4BFDCE5),I64(0x20059D79DEDD7AB2),I64(0x6DABE6D6AE3C446B),I64(0x45E81BF6C991AE7B),
		I64(0x6351AE7CAC68B83E),I64(0xA432E32253B6C711),I64(0xD092A9B991143CD2),I64(0xCAC711032E98B58F),
		I64(0xD8D4C9E02864AC70),I64(0xC5FC550F96C25B89),I64(0xD7EF8DEC903E4276),I64(0x67729EDE7E50F06F),
		I64(0xEAC28C7AF045CF3D),I64(0xB15C1F945460A04A),I64(0x9CFDDEB05BFB1058),I64(0x93C69ABCE3A1FE5E),
		I64(0xEB0380DC4A4BDD6E),I64(0xD20DB1E8F8081874),I64(0x229A8528B7C15E14),I64(0x44291750739FBC28),
		I64(0xD3CCBD4E42060A27),I64(0xF62B1C33F4ED2A97),I64(0x86A8660AE4779905),I64(0xD62E814A2A305025),
		I64(0x477703A7A08D8ADD),I64(0x7B9B0E977AF815C5),I64(0x78C51A60A9EA2330),I64(0xA6ADFB733AAAE3B7),
		I64(0x97E5AA1E3199B60F),I64(0x0000000000000000),I64(0xF4B404629DF10E31),I64(0x5564DB44A6719322),
		I64(0x9207961A59AFEC0D),I64(0x9624A6B88B97A45C),I64(0x363575380A192B1C),I64(0x2C60CD82B595A241),
		I64(0x7D272664C1DC7932),I64(0x7142769FAA94A1C1),I64(0xA1D0DF263B809D13),I64(0x1630E841D4C451AE),
		I64(0xC1DF65AD44FA13D8),I64(0x13D2D445BCF20BAC),I64(0xD915C546926ABE23),I64(0x38CF3D92084DD749),
		I64(0xE766D0272103059D),I64(0xC7634D5EFFDE7F2F),I64(0x077D2455012A7EA4),I64(0xEDBFA82FF16FB199),
		I64(0xAF2A978C39D46146),I64(0x42953FA3C8BBD0DF),I64(0xCB061DA59496A7DC),I64(0x25E7A17DB6EB20B0),
		I64(0x34AA6D6963050FBA),I64(0xA76CF7D580A4F1E4),I64(0xF7EA10954EE338C4),I64(0xFCF2643B24819E93),
		I64(0xCF252D0746AEEF8D),I64(0x4EF06F58A3F3082C),I64(0x563ACFB37563A5D7),I64(0x5086E740CE47C920),
		I64(0x2982F186DDA3F843),I64(0x87696AAC5E798B56),I64(0x5D22BB1D1F010380),I64(0x035E14F7D31236F5),
		I64(0x3CEC0D30DA759F18),I64(0xF3C920379CDB7095),I64(0xB8DB736B571E22BB),I64(0xDD36F5E44052F672),
		I64(0xAAC8AB8851E23B44),I64(0xA857B3D938FE1FE2),I64(0x17F1E4E76ECA43FD),I64(0xEC7EA4894B61A3CA),
		I64(0x9E62C6E132E734FE),I64(0xD4B1991B432C7483),I64(0x6AD6C283AF163ACF),I64(0x1CE9904904A8E5AA),
		I64(0x5FBDA34C761D2726),I64(0xF910583F4CB7C491),I64(0xC6A241F845D06D7C),I64(0x4F3163FE19FD1A7F),
		I64(0xE99C988D2357F9C8),I64(0x8EEE06535D0709A7),I64(0x0EFA48AA0254FC55),I64(0xB4BE23903C56FA48),
		I64(0x763F52CAABBEDF65),I64(0xEEE1BCD8227D876C),I64(0xE345E085F33B4DCC),I64(0x3E731561B369BBBE),
		I64(0x2843FD2067ADEA10),I64(0x2ADCE5710EB1CEB6),I64(0xB7E03767EF44CCBD),I64(0x8DB012A48E153F52),
		I64(0x61CEB62DC5749C98),I64(0xE85D942B9959EB9B),I64(0x4C6F7709CAEF2C8A),I64(0x84377E5B8D6BBDA3),
		I64(0x30895DCBB13D47EB),I64(0x74A04A9BC2A2FBC3),I64(0x6B17CE251518289C),I64(0xE438C4D0F2113368),
		I64(0x1FB784BED7BAD35F),I64(0x9B80FAE55AD16EFC),I64(0x77FE5E6C11B0CD36),I64(0xC858095247849129),
		I64(0x08466059B97090A2),I64(0x01C10CA6BA0E1253),I64(0x6988D6747C040C3A),I64(0x6849DAD2C60A1E69),
		I64(0x5147EBE67449DB73),I64(0xC99905F4FD8A837A),I64(0x991FE2B433CD4A5A),I64(0xF09734C04FC94660),
		I64(0xA28ECBD1E892ABE6),I64(0xF1563866F5C75433),I64(0x4DAE7BAF70E13ED9),I64(0x7CE62AC27BD26B61),
		I64(0x70837A39109AB392),I64(0x90988E4B30B3C8AB),I64(0xB2020B63877296BF),I64(0x156EFCB607D6675B)
	},
	{
		I64(0xE63F55CE97C331D0),I64(0x25B506B0015BBA16),I64(0xC8706E29E6AD9BA8),I64(0x5B43D3775D521F6A),
		I64(0x0BFA3D577035106E),I64(0xAB95FC172AFB0E66),I64(0xF64B63979E7A3276),I64(0xF58B4562649DAD4B),
		I64(0x48F7C3DBAE0C83F1),I64(0xFF31916642F5C8C5),I64(0xCBB048DC1C4A0495),I64(0x66B8F83CDF622989),
		I64(0x35C130E908E2B9B0),I64(0x7C761A61F0B34FA1),I64(0x3601161CF205268D),I64(0x9E54CCFE2219B7D6),
		I64(0x8B7D90A538940837),I64(0x9CD403588EA35D0B),I64(0xBC3C6FEA9CCC5B5A),I64(0xE5FF733B6D24AEED),
		I64(0xCEED22DE0F7EB8D2),I64(0xEC8581CAB1AB545E),I64(0xB96105E88FF8E71D),I64(0x8CA03501871A5EAD),
		I64(0x76CCCE65D6DB2A2F),I64(0x5883F582A7B58057),I64(0x3F7BE4ED2E8ADC3E),I64(0x0FE7BE06355CD9C9),
		I64(0xEE054E6C1D11BE83),I64(0x1074365909B903A6),I64(0x5DDE9F80B4813C10),I64(0x4A770C7D02B6692C),
		I64(0x5379C8D5D7809039),I64(0xB4067448161ED409),I64(0x5F5E5026183BD6CD),I64(0xE898029BF4C29DF9),
		I64(0x7FB63C940A54D09C),I64(0xC5171F897F4BA8BC),I64(0xA6F28DB7B31D3D72),I64(0x2E4F3BE7716EAA78),
		I64(0x0D6771A099E63314),I64(0x82076254E41BF284),I64(0x2F0FD2B42733DF98),I64(0x5C9E76D3E2DC49F0),
		I64(0x7AEB569619606CDB),I64(0x83478B07B2468764),I64(0xCFADCB8D5923CD32),I64(0x85DAC7F05B95A41E),
		I64(0xB5469D1B4043A1E9),I64(0xB821ECBBD9A592FD),I64(0x1B8E0B0E798C13C8),I64(0x62A57B6D9A0BE02E),
		I64(0xFCF1B793B81257F8),I64(0x9D94EA0BD8FE28EB),I64(0x4CEA408AEB654A56),I64(0x23284A47E888996C),
		I64(0x2D8F1D128B893545),I64(0xF4CBAC3132C0D8AB),I64(0xBD7C86B9CA912EBA),I64(0x3A268EEF3DBE6079),
		I64(0xF0D62F6077A9110C),I64(0x2735C916ADE150CB),I64(0x89FD5F03942EE2EA),I64(0x1ACEE25D2FD16628),
		I64(0x90F39BAB41181BFF),I64(0x430DFE8CDE39939F),I64(0xF70B8AC4C8274796),I64(0x1C53AEAAC6024552),
		I64(0x13B410ACF35E9C9B),I64(0xA532AB4249FAA24F),I64(0x2B1251E5625A163F),I64(0xD7E3E676DA4841C7),
		I64(0xA7B264E4E5404892),I64(0xDA8497D643AE72D3),I64(0x861AE105A1723B23),I64(0x38A6414991048AA4),
		I64(0x6578DEC92585B6B4),I64(0x0280CFA6ACBAEADD),I64(0x88BDB650C273970A),I64(0x9333BD5EBBFF84C2),
		I64(0x4E6A8F2C47DFA08B),I64(0x321C954DB76CEF2A),I64(0x418D312A72837942),I64(0xB29B38BFFFCDF773),
		I64(0x6C022C38F90A4C07),I64(0x5A033A240B0F6A8A),I64(0x1F93885F3CE5DA6F),I64(0xC38A537E96988BC6),
		I64(0x39E6A81AC759FF44),I64(0x29929E43CEE0FCE2),I64(0x40CDD87924DE0CA2),I64(0xE9D8EBC8A29FE819),
		I64(0x0C2798F3CFBB46F4),I64(0x55E484223E53B343),I64(0x4650948ECD0D2FD8),I64(0x20E86CB2126F0651),
		I64(0x6D42C56BAF5739E7),I64(0xA06FC1405ACE1E08),I64(0x7BABBFC54F3D193B),I64(0x424D17DF8864E67F),
		I64(0xD8045870EF14980E),I64(0xC6D7397C85AC3781),I64(0x21A885E1443273B1),I64(0x67F8116F893F5C69),
		I64(0x24F5EFE35706CFF6),I64(0xD56329D076F2AB1A),I64(0x5E1EB9754E66A32D),I64(0x28D2771098BD8902),
		I64(0x8F6013F47DFDC190),I64(0x17A993FDB637553C),I64(0xE0A219397E1012AA),I64(0x786B9930B5DA8606),
		I64(0x6E82E39E55B0A6DA),I64(0x875A0856F72F4EC3),I64(0x3741FF4FA458536D),I64(0xAC4859B3957558FC),
		I64(0x7EF6D5C75C09A57C),I64(0xC04A758B6C7F14FB),I64(0xF9ACDD91AB26EBBF),I64(0x7391A467C5EF9668),
		I64(0x335C7C1EE1319ACA),I64(0xA91533B18641E4BB),I64(0xE4BF9A683B79DB0D),I64(0x8E20FAA72BA0B470),
		I64(0x51F907737B3A7AE4),I64(0x2268A314BED5EC8C),I64(0xD944B123B949EDEE),I64(0x31DCB3B84D8B7017),
		I64(0xD3FE65279F218860),I64(0x097AF2F1DC8FFAB3),I64(0x9B09A6FC312D0B91),I64(0xCC6DED78A3C4520F),
		I64(0x3481D9BA5EBFCC50),I64(0x4F2A667F1182D56B),I64(0xDFD9FDD4509ACE94),I64(0x26752045FBBC252B),
		I64(0xBFFC491F662BC467),I64(0xDD593272FC202449),I64(0x3CBBC218D46D4303),I64(0x91B372F817456E1F),
		I64(0x681FAF69BC6385A0),I64(0xB686BBEEBAA43ED4),I64(0x1469B5084CD0CA01),I64(0x98C98009CBCA94AC),
		I64(0x6438379A73D8C354),I64(0xC2CABA2DC0C5FE26),I64(0x3E3B0DBE78D7A9DE),I64(0x50B9EE202D670F04),
		I64(0x4590B27B37EAB0E5),I64(0x6025B4CB36B10AF3),I64(0xFB2C1237079C0162),I64(0xA12F28130C936BE8),
		I64(0x4B37E52E54EB1CCC),I64(0x083A1BA28AD28F53),I64(0xC10A9CD83A22611B),I64(0x9F1425AD7444C236),
		I64(0x069D4CF7E9D3237A),I64(0xEDC56899E7F621BE),I64(0x778C273680865FCF),I64(0x309C5AEB1BD605F7),
		I64(0x8DE0DC52D1472B4D),I64(0xF8EC34C2FD7B9E5F),I64(0xEA18CD3D58787724),I64(0xAAD515447CA67B86),
		I64(0x9989695A9D97E14C),I64(0x0000000000000000),I64(0xF196C63321F464EC),I64(0x71116BC169557CB5),
		I64(0xAF887F466F92C7C1),I64(0x972E3E0FFE964D65),I64(0x190EC4A8D536F915),I64(0x95AEF1A9522CA7B8),
		I64(0xDC19DB21AA7D51A9),I64(0x94EE18FA0471D258),I64(0x8087ADF248A11859),I64(0xC457F6DA2916DD5C),
		I64(0xFA6CFB6451C17482),I64(0xF256E0C6DB13FBD1),I64(0x6A9F60CF10D96F7D),I64(0x4DAAA9D9BD383FB6),
		I64(0x03C026F5FAE79F3D),I64(0xDE99148706C7BB74),I64(0x2A52B8B6340763DF),I64(0x6FC20ACD03EDD33A),
		I64(0xD423C08320AFDEFA),I64(0xBBE1CA4E23420DC0),I64(0x966ED75CA8CB3885),I64(0xEB58246E0E2502C4),
		I64(0x055D6A021334BC47),I64(0xA47242111FA7D7AF),I64(0xE3623FCC84F78D97),I64(0x81C744A11EFC6DB9),
		I64(0xAEC8961539CFB221),I64(0xF31609958D4E8E31),I64(0x63E5923ECC5695CE),I64(0x47107DDD9B505A38),
		I64(0xA3AFE7B5A0298135),I64(0x792B7063E387F3E6),I64(0x0140E953565D75E0),I64(0x12F4F9FFA503E97B),
		I64(0x750CE8902C3CB512),I64(0xDBC47E8515F30733),I64(0x1ED3610C6AB8AF8F),I64(0x5239218681DDE5D9),
		I64(0xE222D69FD2AAF877),I64(0xFE71783514A8BD25),I64(0xCAF0A18F4A177175),I64(0x61655D9860EC7F13),
		I64(0xE77FBC9DC19E4430),I64(0x2CCFF441DDD440A5),I64(0x16E97AAEE06A20DC),I64(0xA855DAE2D01C915B),
		I64(0x1D1347F9905F30B2),I64(0xB7C652BDECF94B34),I64(0xD03E43D265C6175D),I64(0xFDB15EC0EE4F2218),
		I64(0x57644B8492E9599E),I64(0x07DDA5A4BF8E569A),I64(0x54A46D71680EC6A3),I64(0x5624A2D7C4B42C7E),
		I64(0xBEBCA04C3076B187),I64(0x7D36F332A6EE3A41),I64(0x3B6667BC6BE31599),I64(0x695F463AEA3EF040),
		I64(0xAD08B0E0C3282D1C),I64(0xB15B1E4A052A684E),I64(0x44D05B2861B7C505),I64(0x15295C5B1A8DBFE1),
		I64(0x744C01C37A61C0F2),I64(0x59C31CD1F1E8F5B7),I64(0xEF45A73F4B4CCB63),I64(0x6BDF899C46841A9D),
		I64(0x3DFB2B4B823036E3),I64(0xA2EF0EE6F674F4D5),I64(0x184E2DFB836B8CF5),I64(0x1134DF0A5FE47646),
		I64(0xBAA1231D751F7820),I64(0xD17EAA81339B62BD),I64(0xB01BF71953771DAE),I64(0x849A2EA30DC8D1FE),
		I64(0x705182923F080955),I64(0x0EA757556301AC29),I64(0x041D83514569C9A7),I64(0x0ABAD4042668658E),
		I64(0x49B72A88F851F611),I64(0x8A3D79F66EC97DD7),I64(0xCD2D042BF59927EF),I64(0xC930877AB0F0EE48),
		I64(0x9273540DEDA2F122),I64(0xC797D02FD3F14261),I64(0xE1E2F06A284D674A),I64(0xD2BE8C74C97CFD80),
		I64(0x9A494FAF67707E71),I64(0xB3DBD1ECA9908293),I64(0x72D14D3493B2E388),I64(0xD6A30F258C153427)
	}
};

static const uint64_t gost12_iteration_constants[12][8] =
{
	{
		I64(0xdd806559f2a64507),I64(0x05767436cc744d23),I64(0xa2422a08a460d315),I64(0x4b7ce09192676901),
		I64(0x714eb88d7585c4fc),I64(0x2f6a76432e45d016),I64(0xebcb2f81c0657c1f),I64(0xb1085bda1ecadae9)
	},
	{
		I64(0xe679047021b19bb7),I64(0x55dda21bd7cbcd56),I64(0x5cb561c2db0aa7ca),I64(0x9ab5176b12d69958),
		I64(0x61d55e0f16b50131),I64(0xf3feea720a232b98),I64(0x4fe39d460f70b5d7),I64(0x6fa3b58aa99d2f1a)
	},
	{
		I64(0x991e96f50aba0ab2),I64(0xc2b6f443867adb31),I64(0xc1c93a376062db09),I64(0xd3e20fe490359eb1),
		I64(0xf2ea7514b1297b7b),I64(0x06f15e5f529c1f8b),I64(0x0a39fc286a3d8435),I64(0xf574dcac2bce2fc7)
	},
	{
		I64(0x220cbebc84e3d12e),I64(0x3453eaa193e837f1),I64(0xd8b71333935203be),I64(0xa9d72c82ed03d675),
		I64(0x9d721cad685e353f),I64(0x488e857e335c3c7d),I64(0xf948e1a05d71e4dd),I64(0xef1fdfb3e81566d2)
	},
	{
		I64(0x601758fd7c6cfe57),I64(0x7a56a27ea9ea63f5),I64(0xdfff00b723271a16),I64(0xbfcd1747253af5a3),
		I64(0x359e35d7800fffbd),I64(0x7f151c1f1686104a),I64(0x9a3f410c6ca92363),I64(0x4bea6bacad474799)
	},
	{
		I64(0xfa68407a46647d6e),I64(0xbf71c57236904f35),I64(0x0af21f66c2bec6b6),I64(0xcffaa6b71c9ab7b4),
		I64(0x187f9ab49af08ec6),I64(0x2d66c4f95142a46c),I64(0x6fa4c33b7a3039c0),I64(0xae4faeae1d3ad3d9)
	},
	{
		I64(0x8886564d3a14d493),I64(0x3517454ca23c4af3),I64(0x06476983284a0504),I64(0x0992abc52d822c37),
		I64(0xd3473e33197a93c9),I64(0x399ec6c7e6bf87c9),I64(0x51ac86febf240954),I64(0xf4c70e16eeaac5ec)
	},
	{
		I64(0xa47f0dd4bf02e71e),I64(0x36acc2355951a8d9),I64(0x69d18d2bd1a5c42f),I64(0xf4892bcb929b0690),
		I64(0x89b4443b4ddbc49a),I64(0x4eb7f8719c36de1e),I64(0x03e7aa020c6e4141),I64(0x9b1f5b424d93c9a7)
	},
	{
		I64(0x7261445183235adb),I64(0x0e38dc92cb1f2a60),I64(0x7b2b8a9aa6079c54),I64(0x800a440bdbb2ceb1),
		I64(0x3cd955b7e00d0984),I64(0x3a7d3a1b25894224),I64(0x944c9ad8ec165fde),I64(0x378f5a541631229b)
	},
	{
		I64(0x74b4c7fb98459ced),I64(0x3698fad1153bb6c3),I64(0x7a1e6c303b7652f4),I64(0x9fe76702af69334b),
		I64(0x1fffe18a1b336103),I64(0x8941e71cff8a78db),I64(0x382ae548b2e4f3f3),I64(0xabbedea680056f52)
	},
	{
		I64(0x6bcaa4cd81f32d1b),I64(0xdea2594ac06fd85d),I64(0xefbacd1d7d476e98),I64(0x8a1d71efea48b9ca),
		I64(0x2001802114846679),I64(0xd8fa6bbbebab0761),I64(0x3002c6cd635afe94),I64(0x7bcd9ed0efc889fb)
	},
	{
		I64(0x48bc924af11bd720),I64(0xfaf417d5d9b21b99),I64(0xe71da4aa88e12852),I64(0x5d80ef9d1891cc86),
		I64(0xf82012d430219f9b),I64(0xcda43c32bcdf1d77),I64(0xd21380b00449b17a),I64(0x378ee767f11631ba)
	}
};

static const uint64_t zero_512[8] = { 0,0,0,0,0,0,0,0 };

/**
 * Initialize algorithm context.
 *
 * @param ctx context to initialize
 * @param hash_size the size of the digest in bytes
 */
static RHASH_INLINE void rhash_gost12_init(gost12_ctx* ctx, unsigned hash_size)
{
	memset(ctx, 0, sizeof(gost12_ctx));
	if (hash_size != gost12_512_hash_size)
		memset(ctx->h, 1, gost12_512_hash_size);
	ctx->hash_size = hash_size;
}

/**
 * Initialize algorithm context for 256-bit sized digest.
 *
 * @param ctx context to initialize
 * @param hash_size the size of the digest in bytes
 */
void rhash_gost12_256_init(gost12_ctx* ctx)
{
	rhash_gost12_init(ctx, gost12_256_hash_size);
}

/**
 * Initialize algorithm context for 512-bit sized digest.
 *
 * @param ctx context to initialize
 * @param hash_size the size of the digest in bytes
 */
void rhash_gost12_512_init(gost12_ctx* ctx)
{
	rhash_gost12_init(ctx, gost12_512_hash_size);
}

#define xor_uint512(x, y, z) { \
	z[0] = x[0] ^ y[0]; \
	z[1] = x[1] ^ y[1]; \
	z[2] = x[2] ^ y[2]; \
	z[3] = x[3] ^ y[3]; \
	z[4] = x[4] ^ y[4]; \
	z[5] = x[5] ^ y[5]; \
	z[6] = x[6] ^ y[6]; \
	z[7] = x[7] ^ y[7]; \
}

static void LPSX(const uint64_t* a, const uint64_t* b, uint64_t* result)
{
	register uint64_t r0, r1, r2, r3, r4, r5, r6, r7;
	int i;

	/* calculate xor_uint512(a, b) */
	r0 = a[0] ^ b[0];
	r1 = a[1] ^ b[1];
	r2 = a[2] ^ b[2];
	r3 = a[3] ^ b[3];
	r4 = a[4] ^ b[4];
	r5 = a[5] ^ b[5];
	r6 = a[6] ^ b[6];
	r7 = a[7] ^ b[7];

	/* apply L P S transformations */
	for (i = 0; i <= 7; i++)
	{
		result[i]  = TR[0][(r0 >> (i << 3)) & 0xFF];
		result[i] ^= TR[1][(r1 >> (i << 3)) & 0xFF];
		result[i] ^= TR[2][(r2 >> (i << 3)) & 0xFF];
		result[i] ^= TR[3][(r3 >> (i << 3)) & 0xFF];
		result[i] ^= TR[4][(r4 >> (i << 3)) & 0xFF];
		result[i] ^= TR[5][(r5 >> (i << 3)) & 0xFF];
		result[i] ^= TR[6][(r6 >> (i << 3)) & 0xFF];
		result[i] ^= TR[7][(r7 >> (i << 3)) & 0xFF];
	}
}

/*
 * Implementaion of the function g_N(h,m) = E(LPS(h xor N),m) xor h xor m,
 * where E(K, ) = X[K1 3 ]L PSX[K12] .. . L PSX[K2]LPSX[K1](m).
 */
static void g_N(const uint64_t N[], uint64_t h[], const uint64_t m[])
{
	uint64_t K_i[8];
	uint64_t state[8];
	unsigned int i;

	/* the first iteration of E(K_i, m): calculate and apply K_1 */
	LPSX(h, N, K_i);
	LPSX(K_i, m, state);

	/* rounds 2,...,11 of E(K_i, m) */
#if 0
	LPSX(K_i, gost12_iteration_constants[0], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[1], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[2], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[3], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[4], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[5], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[6], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[7], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[8], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[9], K_i);
	LPSX(K_i, state, state);
	LPSX(K_i, gost12_iteration_constants[10], K_i);
	LPSX(K_i, state, state);
#else
	for (i = 0; i < 11; i++)
	{
		LPSX(K_i, gost12_iteration_constants[i], K_i);
		LPSX(K_i, state, state);
	}
#endif

	/* the round 12 of E(K_i, m) */
	LPSX(K_i, gost12_iteration_constants[11], K_i);
	xor_uint512(K_i, state, state);

	/* the last step: calculate h = (state XOR h XOR m) */
	xor_uint512(state, h, state);
	xor_uint512(state, m, h);
}

static RHASH_INLINE void add_uint512(uint64_t sum[], const uint64_t x[])
{
	/* usless but fun optimization for x86 */
#if defined(USE_GCC_ASM_IA32)
	__asm(
		"movl   (%1), %%eax\n\taddl %%eax,   (%0)\n\t"
		"movl  4(%1), %%ecx\n\tadcl %%ecx,  4(%0)\n\t"
		"movl  8(%1), %%eax\n\tadcl %%eax,  8(%0)\n\t"
		"movl 12(%1), %%ecx\n\tadcl %%ecx, 12(%0)\n\t"
		"movl 16(%1), %%eax\n\tadcl %%eax, 16(%0)\n\t"
		"movl 20(%1), %%ecx\n\tadcl %%ecx, 20(%0)\n\t"
		"movl 24(%1), %%eax\n\tadcl %%eax, 24(%0)\n\t"
		"movl 28(%1), %%ecx\n\tadcl %%ecx, 28(%0)\n\t"
		"movl 32(%1), %%eax\n\tadcl %%eax, 32(%0)\n\t"
		"movl 36(%1), %%ecx\n\tadcl %%ecx, 36(%0)\n\t"
		"movl 40(%1), %%eax\n\tadcl %%eax, 40(%0)\n\t"
		"movl 44(%1), %%ecx\n\tadcl %%ecx, 44(%0)\n\t"
		"movl 48(%1), %%eax\n\tadcl %%eax, 48(%0)\n\t"
		"movl 52(%1), %%ecx\n\tadcl %%ecx, 52(%0)\n\t"
		"movl 56(%1), %%eax\n\tadcl %%eax, 56(%0)\n\t"
		"movl 60(%1), %%ecx\n\tadcl %%ecx, 60(%0)\n\t"
		: : "r" (sum), "r" (x)
		: "eax", "ecx", "memory", "cc" );
#elif defined(USE_GCC_ASM_X64)
	__asm(
		"movq (%1), %%rax\n\taddq %%rax, (%0)\n\t"
		"movq 8(%1), %%rax\n\tadcq %%rax, 8(%0)\n\t"
		"movq 16(%1), %%rax\n\tadcq %%rax, 16(%0)\n\t"
		"movq 24(%1), %%rax\n\tadcq %%rax, 24(%0)\n\t"
		"movq 32(%1), %%rax\n\tadcq %%rax, 32(%0)\n\t"
		"movq 40(%1), %%rax\n\tadcq %%rax, 40(%0)\n\t"
		"movq 48(%1), %%rax\n\tadcq %%rax, 48(%0)\n\t"
		"movq 56(%1), %%rax\n\tadcq %%rax, 56(%0)\n\t"
		: : "r" (sum), "r" (x)
		: "rax", "memory", "cc" );
#else /* defined(USE_GCC_ASM_IA32) */
	int i;
	uint64_t carry = 0;

	/* compute the 512-bit sum */
	for (i = 0; i < 8; i++)
	{
		sum[i] += x[i] + carry;
		carry = (sum[i] < x[i] ? 1 : sum[i] == x[i] ? carry : 0);
	}
#endif /* USE_GCC_ASM_IA32 */
}

static const uint64_t stage2_constant[8] = { I64(512), 0, 0, 0, 0, 0, 0, 0 };

static RHASH_INLINE void rhash_gost12_stage2(gost12_ctx* ctx, uint64_t m[])
{
	g_N(ctx->N, ctx->h, m);
	add_uint512(ctx->N, stage2_constant);
	add_uint512(ctx->S, m);
}

void rhash_gost12_update(gost12_ctx* ctx, const unsigned char* msg, size_t size)
{
	if (ctx->index)
	{
		size_t rest = gost12_block_size - ctx->index;

		le64_copy(ctx->message, ctx->index, msg, (size < rest ? size : rest));
		ctx->index += (unsigned)size;
		if (size < rest)
			return;

		/* process partial block */
		rhash_gost12_stage2(ctx, ctx->message);
		msg  += rest;
		size -= rest;
		ctx->index = 0;
	}
	if (IS_LITTLE_ENDIAN && IS_ALIGNED_64(msg))
	{
		while (size >= gost12_block_size)
		{
			rhash_gost12_stage2(ctx, (uint64_t*)msg);
			msg += gost12_block_size;
			size -= gost12_block_size;
		}
	} else {
		while (size >= gost12_block_size)
		{
			le64_copy(ctx->message, 0, msg, gost12_block_size);
			rhash_gost12_stage2(ctx, ctx->message);
			msg += gost12_block_size;
			size -= gost12_block_size;
		}
	}
	if (size)
	{
		ctx->index = (unsigned)size;
		le64_copy(ctx->message, 0, msg, size); /* save leftovers */
	}
}

void rhash_gost12_final(gost12_ctx* ctx, unsigned char* result)
{
	uint64_t unprocessed_bits_count[8] = { 0,0,0,0,0,0,0,0 };
	size_t index_u64 = ctx->index >> 3;
	unsigned shift = (ctx->index & 7) * 8;

	unprocessed_bits_count[0] = ctx->index * 8;
	ctx->message[index_u64]   &= ~(I64(0xFFFFFFFFFFFFFFFF) << shift);
	ctx->message[index_u64++] ^= I64(0x01) << shift;
	memset(&ctx->message[index_u64], 0, gost12_block_size - index_u64 * 8);

	/* apply gost12 stage 3 */
	g_N(ctx->N, ctx->h, ctx->message);
	add_uint512(ctx->N, unprocessed_bits_count);
	add_uint512(ctx->S, ctx->message);
	g_N(zero_512, ctx->h, ctx->N);
	g_N(zero_512, ctx->h, ctx->S);

	le64_copy(result, 0, &(ctx->h[8 - ctx->hash_size / 8]), ctx->hash_size);
}
